package com.maycur.ctrip.util;

import com.maycur.ctrip.domain.EntInfo;
import com.maycur.ctrip.dto.AccessTokenResponse;
import com.maycur.ctrip.dto.Authentification;
import com.maycur.ctrip.exception.ApiException;
import com.maycur.ctrip.mybatis.mapper.EntInfoMapper;
import com.maycur.ctrip.service.RedisService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.Map;
import java.util.TreeMap;

/**
 * Created by zhouchunjie on 16/1/25.
 */
@Component
public class CtripApiUtil {

    public static final Logger logger = LoggerFactory.getLogger(CtripApiUtil.class);

    @Autowired
    private RedisService redisService;

    @Autowired
    private EntInfoMapper entInfoMapper;


    /**
     * 获取accessToken
     * 先去和缓存中读取,如果未找到则重新申请
     *
     * @param entCode 企业编码
     * @param isForce 强制更新
     * @return
     */
    public Authentification getAccessAuth(String entCode, boolean isForce) throws ApiException {
        Authentification accessAuth = null;
        if (!isForce) {
            //从缓存中获取已申请的且未过期的accessAuth
            accessAuth = redisService.hGetGeneric(Constant.ENT_TOKEN_KEY_IN_REDIS, entCode, Authentification.class);
        }

        if (accessAuth == null) {
            //重新从携程获取申请
            accessAuth = applyAccessAuth(entCode);
            if (accessAuth == null) {
                logger.error("Failed to get the access ticket for kicking off request");
                throw new ApiException("Failed to get access authentification");
            }
            //将token存入redis中,并设置过期时长
            redisService.hSaveGenericWithExpireTime(Constant.ENT_TOKEN_KEY_IN_REDIS, entCode, accessAuth, Constant.ENT_ACCESS_TOKEN_EXPIRED_SECONDS);
        }

        return accessAuth;
    }

    /**
     * 重新获取accessAuth
     *
     * @param entCode 企业编码
     * @return
     */
    private Authentification applyAccessAuth(String entCode) {

        EntInfo entInfo = entInfoMapper.selectEntInfo(entCode);

        if(entInfo == null || StringUtils.isEmpty(entInfo.getAppKey()) || StringUtils.isEmpty(entInfo.getAppSecurity())) {
            logger.error("Could not identify the appKey/appSecurity for enterprise(entCode={})", entCode);
            throw new ApiException("Could not identify the appKey/appSecurity for enterprise");
        }
        Map<String, Object> params = new TreeMap<>();
        params.put(Constant.PARAM_APP_KEY, entInfo.getAppKey());
        params.put(Constant.PARAM_APP_SECURITY, entInfo.getAppSecurity());

        //发起Post请求
        AccessTokenResponse responseDto = HttpUtil.httpPost(Constant.TICKET_URL, params, AccessTokenResponse.class);

        return (responseDto == null) ? null : new Authentification(entInfo.getAppKey(), responseDto.getTicket());
    }


/*
    */
/**
     * add AUTH parameter and encode all other business parameters
     * @param entCode 企业编码
     * @param businessParams
     * @return
     *//*

    private Map<String, Object> encodeParams(String entCode, Map<String, Object> businessParams) throws ApiException {
        logger.info("Prepare the parameters for generating sign");
        Map<String, Object> params = new TreeMap<>();

        //添加 appKey等
        params.put(Constant.PARAM_AUTH, getAccessAuth(entCode, false));

        for (Map.Entry<String, Object> entry : businessParams.entrySet()) {
            if (entry.getValue() instanceof String) {
                try {
                    params.put(entry.getKey(), URLEncoder.encode(entry.getValue().toString(), "utf-8"));
                } catch (UnsupportedEncodingException e) {
                    logger.error("Failed to convert business parameter entry {} as utf-8", entry.getValue());
                    throw new ApiException("Failed to convert business parameter entry");
                }
            } else {
                params.put(entry.getKey(), entry.getValue());
            }

        }

        return params;
    }

    */
/**
     * 动态生成Post请求的map
     *
     * @param businessParams
     * @param businessParams
     * @return
     *//*

    public Map<String, Object> generatePostRequestMap(String entCode, Map<String, Object> businessParams) throws ApiException {

        Map<String, Object> params = encodeParams(entCode, businessParams);

        return params;
    }

    */
/**
     * 动态生成Get请求的String Params
     *
     * @param businessParams
     * @return
     *//*

    public String generateGetRequestParamStr(String entCode, Map<String, Object> businessParams) throws ApiException {
        Map<String, Object> params = new TreeMap<>();
        String paramStr = "";

        params = encodeParams(entCode, businessParams);

        for (Map.Entry<String, Object> entry : params.entrySet()) {
            if (!StringUtils.isEmpty(paramStr)) {
                paramStr += "&";
            }
            if (entry.getValue() instanceof String) {
                try {
                    paramStr += entry.getKey() + "=" + URLEncoder.encode(entry.getValue().toString(), "utf-8");
                } catch (UnsupportedEncodingException e) {
                    logger.error("Failed to convert business parameter entry {} as utf-8", entry.getValue());
                    throw new ApiException("Failed to convert business parameter entry", e);
                }
            } else {
                paramStr += entry.getKey() + "=" + entry.getValue();
            }
        }

        return paramStr;
    }
*/


}
